
#ifndef _TTG_THREADS_WIN32_WIN32THREADS_
#define _TTG_THREADS_WIN32_WIN32THREADS_
#include "Common/Definitions.h"

#include <windows.h>

#include "../Threads.h"
#include "../AtomicValues.h"
#include "../Events.h"
#include "../CriticalSections.h"

namespace ttg
{
	namespace threads
	{
		namespace win32
		{
			enum Win32ThreadState
			{
				Working = 0,			//works
				SleepingFast = 1,		//active sleep
				SleepingDeep = 2,		//passive sleep
			};
			//Base class for any threads.
			class Win32Thread :public ttg_internal::threads::Thread
			{
				private:
					uintptr_t winthread;
					FastEvent sleep_fast;			//event for fast sleep.
					SlowEvent sleep_slow;			//event for slow sleep.
					Win32ThreadState state;			//current state of thread.
					FastCriticalSection sleep_cs;	//section for "state" accessing.
					bool isstarted;					//is thread started?
					bool shouldterminate;			//should thread be terminated?
					bool should_resleep;			//should thread change type of sleep?
					void sleep(bool is_fast, bool is_waiting, double wait_time = 0.0);
				protected:
					//Thread suspends itself for long time (via SlowEvent).
					//Can be woken by wake().
					virtual void sleepDeep();
					//Threads suspends itself for required time interval (via SlowEvent).
					//Note: it can be rised by "wake()".
					virtual void sleepDeep(double seconds);
					//Thread suspends itself for short time (via FastEvent).
					//Can be woken by wake().
					virtual void sleepFast();
					//Threads suspends itself for required time interval (via FastEvent).
					//Note: it can be rised by "wake()".
					virtual void sleepFast(double seconds);
					//Enter point. Should never return.
					virtual void work() = 0;
				public:
					//Creates context and [optionally] starts thread.
					Win32Thread(bool shouldstart);
					//Wakes thread. If it does not sleep, does nothing.
					virtual void wake();
					//Starts thread (if it wasn't started by constructor).
					virtual void start();
					//Request for delayed termination.
					//Will be perfromed after wake().
					virtual void terminate();
					//Checks thread status.
					virtual bool isSleeping();
					//Changes type of sleep.
					//If thread does not sleep, does nothing.
					virtual void reSleep(bool fast_sleep);
					//Tryes to set ideal core.
					virtual void setIdealCore(size_t core);
					virtual ~Win32Thread();
				friend unsigned __stdcall entryPoint(void *vdata);
			};
			//Win32 implementation of thread identification.
			class Win32CurrentThread
			{
				public:
					static ttg::math::uint64 getIdentifier()
					{ return (ttg::math::uint64)GetCurrentThreadId(); }
					static void sleep(double time)
					{ Sleep((DWORD)(time * 1000)); }
			};
		}
	}
}

namespace ttg
{
	namespace threads
	{
		typedef win32::Win32Thread Thread;
		typedef win32::Win32CurrentThread CurrentThread;
	}
}

#endif
